﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Stats.Distribution
{
    public class StandardBase : List<Double>
    {
        public Double Mean
        {
            get
            {
                return this.Average();
            }
        }

        /// <summary>
        /// Find medium of the list of numbers.
        /// </summary>
        /// <param name="Values"></param>
        /// <returns></returns>
        public Double Medium
        {
            get
            {
                this.Sort();
                if (this.Count > 0)
                {
                    Int32 Middle = Convert.ToInt32(this.Count / 2);

                    return this[Middle];
                }
                else
                {
                    return 0.0;
                }
            }
        }

        /// <summary>
        /// Calculate the variance of the list of numbers.
        /// </summary>
        /// <param name="Values"></param>
        /// <returns></returns>
        public Double Varience
        {
            get
            {
                Double DiffernceTotal = 0.0;
                foreach (Double Value in this)
                {
                    Double Difference = Value - this.Mean;
                    Double DifferenceSquared = Difference * Difference;
                    DiffernceTotal += DifferenceSquared;
                }

                return DiffernceTotal / (this.Count - 1);
            }
        }

        /// <summary>
        /// Calculate the standard deviation of the list of numbers.
        /// </summary>
        /// <param name="Values"></param>
        /// <returns></returns>
        public Double StandardDeviation
        {
            get
            {
                return Math.Sqrt(this.Varience);
            }
        }

        /// <summary>
        /// Calculate the standard deviation of the list of numbers.
        /// </summary>
        /// <param name="Values"></param>
        /// <returns></returns>
        public Double σ
        {
            get
            {
                return this.StandardDeviation;
            }
        }

        /// <summary>
        /// Calculate the zscore off a value.
        /// </summary>
        /// <param name="X"></param>
        /// <returns></returns>
        public Double zScore(Double X)
        {
            return ((X - this.Mean) / this.StandardDeviation);
        }
    }
}
